#include "natiavscanlog.h"
#include "csingleteon.h"
#include "compixmap.h"
#include "invokers/invokerfactory.h"

//#include <DFontSizeManager>
//#include <DApplicationHelper>
#include <QListView>
//#include <DTitlebar>
#include <QApplication>

#include <QDebug>
#include <QTime>
#include <QHeaderView>
#include <QDir>
#include <QDesktopServices>
#include <QUrl>
#include <QFileDialog>
//#include <DBlurEffectWidget>

#define TABLE_SPACE 5 //表栏两边间距
#define DIALOG_WIDTH 500 //dialog  宽度
#define DIALOG_HEIGHT 500 //dialog  高度
#define TABLEVIEW_WIDTH 480 //tableview  宽度
#define TABLEVIEW_HEIGHT 320 //tableview  高度
#define TABLEVIEW_ROW_HEIGHT 40 //tableview 每列高度

#define TABLE_COL_TIME 0 //table表 第二列 时间
#define TABLE_COL_TYPE 1 //table表 第三列 扫描类型
#define TABLE_COL_RESULT 2 //table表 第四列 结果
#define TABLE_COL_ACTION 3 //table表 第五列 操作
#define TABLE_COL_CHECK_STATUS 4 //table表 第六列 选择状态
#define TABLE_COL_FILE_NAME 5 //table表 第七列 文件名
#define TABLE_COL_ADD_TIME 6 //table表 第八列 时间
#define TABLE_COL_STATUS 7 //table表 第九列 扫描状态
#define TABLE_COL_RES 8 //table表 第十列 结果

#define TABLE_COL_1_WIDTH 180 //table表 第二列 时间宽度
#define TABLE_COL_2_WIDTH 120 //table表 第三列 类型宽度
#define TABLE_COL_3_WIDTH 110 //table表 第四列 结果宽度
#define TABLE_COL_4_WIDTH 70 //table表 第五列 操作宽度
#define SPINNER_WIDTH 100 //spinner 宽度
#define SPINNER_HEIGHT 100 //spinner 高度
#define PAGE_TABLE 0 //表格页面
#define PAGE_SPINNER 1 //加载页面
#define PB_DELETE_WIDTH 140 //删除日志按钮宽度
#define PB_DELETE_HEIGHT 37 //删除日志按钮高度
#define LEFT_MARGINS 0 //左边距
#define TOP_MARGINS 0 //上边距
#define RIGHT_MARGINS 0 //右边距离
#define BUTTOM_MARGINS 0 //下边距离
#define SPACING 5 //布局间隙
#define ACTION_ICON_WIDTH 16 //操作图表 宽度
#define ACTION_ICON_HEIGHT 16 //操作图标 高度

#define SET_ACC_NAME(contral, name) SET_ACCESS_NAME(contral, natiavScanLog, name)

NatiavScanLog::NatiavScanLog(QWidget *parent)
    : QFrame(parent)
    , m_monitorInterFaceServer(nullptr)
    , m_checkBoxAll(new QCheckBox(this))
    , m_pBLog(new QPushButton(this))
    , m_model(nullptr)
    , m_tableView(nullptr)
//    , m_guiHelper(DGuiApplicationHelper::instance())
    , m_proLable(nullptr)
    , m_curret(0)
{
    //安全中心联网管控dbus服务
    m_monitorInterFaceServer = InvokerFactory::GetInstance().CreateInvoker("com.deepin.defender.MonitorNetFlow",
                                                                           "/com/deepin/defender/MonitorNetFlow",
                                                                           "com.deepin.defender.MonitorNetFlow",
                                                                           ConnectType::SYSTEM, this);

    SET_ACC_NAME(m_checkBoxAll, checkBoxAll);
    SET_ACC_NAME(m_pBLog, logButton);
    installEventFilter(this);
    // 大小设置
    this->resize(DIALOG_WIDTH, DIALOG_HEIGHT);
    this->setMinimumSize(QSize(DIALOG_WIDTH, DIALOG_HEIGHT));
    this->setMaximumSize(QSize(DIALOG_WIDTH, DIALOG_HEIGHT));

    // 设置为Dialog
    setWindowFlags(Qt::Dialog);
    // 设置为阻态
    setWindowModality(Qt::ApplicationModal);
    // 背景透明化
//    setAttribute(Qt::WA_TranslucentBackground);
    // 背景透明化
//    DBlurEffectWidget *m_blurEffect = new DBlurEffectWidget(this);
//    SET_ACC_NAME(m_blurEffect, blurWidge);
//    m_blurEffect->setBlendMode(DBlurEffectWidget::BehindWindowBlend);
//    // 设置模糊大小
//    m_blurEffect->resize(size());
//    m_blurEffect->lower();

    // 界面初始化
    initGUI();

    // 主题变换 改变部分图标颜色
//    connect(m_guiHelper, SIGNAL(themeTypeChanged(ColorType)), this, SLOT(themeTypeChange(ColorType)));
    // 全选按钮改变信号
    connect(m_checkBoxAll, SIGNAL(stateChanged(int)), this, SLOT(checkAll(int)));
    // 删除日志
    connect(m_pBLog, SIGNAL(clicked()), this, SLOT(deleteLog()));
    // 表头改变宽度
    connect(m_tableView->horizontalHeader(), SIGNAL(sectionResized(int, int, int)), this, SLOT(updateTableForWidth(int, int, int)));
    connect(m_tableView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(currentRowClicked(const QModelIndex &)));

    // 点击表头触发排序
    connect(m_tableView->horizontalHeader(), SIGNAL(sectionClicked(int)), this, SLOT(sortByTableHeaderClicked(int)));
}

NatiavScanLog::~NatiavScanLog()
{
    m_model->clear();
    m_model->deleteLater();
    m_model = nullptr;
}

// 布局
void NatiavScanLog::initGUI()
{
    // 主布局
    QVBoxLayout *mainlayout = new QVBoxLayout(this);
    // 边距离
    mainlayout->setContentsMargins(LEFT_MARGINS, TOP_MARGINS, RIGHT_MARGINS, BUTTOM_MARGINS + 10);
    mainlayout->setSpacing(SPACING);
    QHBoxLayout *titleBarLayout = new QHBoxLayout();
    titleBarLayout->setContentsMargins(LEFT_MARGINS, TOP_MARGINS, RIGHT_MARGINS, BUTTOM_MARGINS);
    // 右上角关闭按钮
//    DTitlebar *titleBar = new DTitlebar(this);
//    SET_ACC_NAME(titleBar, titleBar);
//    titleBar->setBackgroundTransparent(true);
//    titleBar->setTitle(" ");
//    titleBar->setMenuVisible(false);
//    titleBarLayout->addWidget(titleBar, 0, Qt::AlignRight | Qt::AlignTop);

    mainlayout->addLayout(titleBarLayout);
    // 标题  查杀日志
    QLabel *label_title = new QLabel(tr("Scan Logs"), this);
    SET_ACC_NAME(label_title, titleLable);
    label_title->setAlignment(Qt::AlignCenter);
    QFont ft = label_title->font();
    ft.setBold(true);
    label_title->setFont(ft);
//    DFontSizeManager::instance()->bind(label_title, DFontSizeManager::T5);
    mainlayout->addWidget(label_title, 0, Qt::AlignHCenter);

    // 中间表格布局
    QWidget *CenterWidget = new QWidget(this);
    SET_ACC_NAME(CenterWidget, CenterWidget);
    CenterWidget->setMinimumWidth(TABLEVIEW_WIDTH);
    CenterWidget->setLayout(initTableWidget());
    mainlayout->addWidget(CenterWidget, 0, Qt::AlignHCenter);

    QHBoxLayout *hlayout = new QHBoxLayout();
    hlayout->setContentsMargins(15, TOP_MARGINS, 15, BUTTOM_MARGINS);

    // 全选
    m_checkBoxAll->setText(tr("Select All"));
    hlayout->addWidget(m_checkBoxAll, 0, Qt::AlignLeft);
    hlayout->addStretch(1);
    m_proLable = new QLabel(this);
    SET_ACC_NAME(m_proLable, proLable);
    hlayout->addWidget(m_proLable, 0, Qt::AlignRight);
    mainlayout->addLayout(hlayout);

    // 删除按钮
    m_pBLog->setText(tr("Delete Log"));

    m_pBLog->setMinimumSize(QSize(PB_DELETE_WIDTH, PB_DELETE_HEIGHT));
    m_pBLog->setMaximumSize(QSize(PB_DELETE_WIDTH, PB_DELETE_HEIGHT));
    refreshBtnLogText(); // 初始化更新一下按钮文案
    mainlayout->addWidget(m_pBLog, 0, Qt::AlignBottom | Qt::AlignHCenter);

    m_checkBoxAll->setDisabled(true);
    m_pBLog->setDisabled(true);
}

//初始化tableview
QHBoxLayout *NatiavScanLog::initTableWidget()
{
    QHBoxLayout *layout = new QHBoxLayout;
    layout->setMargin(0);
    layout->setSpacing(0);

    // 表格属性设置
    m_tableView = new QTableView(this);
    SET_ACC_NAME(m_tableView, tableView);
    SET_ACC_NAME(m_tableView->viewport(), viewPort);
    m_tableView->verticalHeader()->setDefaultSectionSize(TABLEVIEW_ROW_HEIGHT);
    m_tableView->verticalHeader()->setVisible(false);
    m_tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
    m_tableView->setSelectionMode(QAbstractItemView::SingleSelection);
    m_tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    m_tableView->setFrameShape(QTableView::NoFrame);
    m_tableView->setShowGrid(false);
    m_tableView->setSortingEnabled(true);

    // 连接表格与模型
    m_model = new QStandardItemModel(this);
    m_tableView->setModel(m_model);
    // 设置表格样式
    def::widgets::DefenderTable *defender = new def::widgets::DefenderTable(this);
    defender->setHeadViewSortHide(TABLE_COL_ACTION);
    defender->setTableAndModel(m_tableView, m_model);
    layout->addWidget(defender);
    // 时间
    QStandardItem *standaritem1 = new QStandardItem(tr("Time"));
    standaritem1->setTextAlignment(Qt::AlignLeft);
    // 扫描类型
    QStandardItem *standaritem2 = new QStandardItem(tr("Scan type"));
    standaritem2->setTextAlignment(Qt::AlignLeft);
    // 结果
    QStandardItem *standaritem3 = new QStandardItem(tr("Results"));
    standaritem3->setTextAlignment(Qt::AlignLeft);
    // 操作
    QStandardItem *standaritem4 = new QStandardItem(tr("Action"));
    standaritem4->setTextAlignment(Qt::AlignLeft);

    m_model->setHorizontalHeaderItem(TABLE_COL_TIME, standaritem1);
    m_model->setHorizontalHeaderItem(TABLE_COL_TYPE, standaritem2);
    m_model->setHorizontalHeaderItem(TABLE_COL_RESULT, standaritem3);
    m_model->setHorizontalHeaderItem(TABLE_COL_ACTION, standaritem4);
    // 选择状态
    m_model->setHorizontalHeaderItem(TABLE_COL_CHECK_STATUS, new QStandardItem("status"));
    // 文件名
    m_model->setHorizontalHeaderItem(TABLE_COL_FILE_NAME, new QStandardItem("fileName"));
    // 添加时间
    m_model->setHorizontalHeaderItem(TABLE_COL_ADD_TIME, new QStandardItem("addTime"));

    // 表格每列设置
    m_tableView->setColumnWidth(TABLE_COL_TIME, TABLE_COL_1_WIDTH);
    m_tableView->setColumnWidth(TABLE_COL_TYPE, TABLE_COL_2_WIDTH);
    m_tableView->setColumnWidth(TABLE_COL_RESULT, TABLE_COL_3_WIDTH);
    m_tableView->setColumnWidth(TABLE_COL_ACTION, TABLE_COL_4_WIDTH);
    // 隐藏文件名列
    m_tableView->setColumnHidden(TABLE_COL_CHECK_STATUS, true);
    m_tableView->setColumnHidden(TABLE_COL_FILE_NAME, true);
    m_tableView->setColumnHidden(TABLE_COL_ADD_TIME, true);
    m_tableView->setColumnHidden(TABLE_COL_STATUS, true);
    m_tableView->setColumnHidden(TABLE_COL_RES, true);
    // 不设置高亮
    m_tableView->horizontalHeader()->setHighlightSections(false);
    return layout;
}

//获得加载的数据
void NatiavScanLog::getlogData()
{
    // 异常文件
    QStringList errorFiles;
    // log 列表清空
    m_logFile.clear();
    // 当前文件夹路径
    m_currentDir = QString("%1/.deepin-defender/natiav/").arg(QDir::homePath());
    QDir dir(m_currentDir);
    QStringList fileInfo;
    fileInfo = dir.entryList();
    for (int i = 0; i < fileInfo.size(); i++) {
        if (fileInfo.at(i).contains(".log")) {
            // 日志文件列表
            m_logFile.append(fileInfo.at(i));
        }
    }
    // 遍历每一个文件
    for (int i = 0; i < m_logFile.size(); i++) {
        // 文件路径
        QString filePath = m_currentDir + m_logFile.at(i);
        QFile f(filePath);
        if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) {
            qDebug() << "Open loglist failed." << endl;
            continue;
        }
        // 输入流
        QTextStream inputStream(&f);
        QStringList linelist;
        // 起始行
        int j = 0;
        // 读取 0-11 行的有效信息
        while (!inputStream.atEnd() && j++ < 14) {
            // 读取每一行
            QString lineStr = inputStream.readLine();
            if (!lineStr.isNull()) {
                // 有效数据
                linelist.append(lineStr);
            }
        }
        f.close();

        // mxz 10/29 https://pms.uniontech.com/zentao/bug-view-52676.html
        // 必须读取14 行信息
        if (linelist.size() == 14) {
            // 校验文本内容
            //bool checkContextFlage = checkContext(linelist);
            if (checkContext(linelist)) {
                // 展现的数据类型
                ScanLogInfo scanlogInfo;
                // 时间
                QString dateTime = "";
                // 类型
                QString scanType = "";
                // 异常数量
                QString threatCount = "";
                // 截取出要展现的数据   依据中文的冒号  和英文的冒号
                if (linelist.at(1).split("：").size() == 2) {
                    // 扫描时间
                    dateTime = linelist.at(2).split("：").at(1);
                    scanType = linelist.at(13).split(">>").at(1).trimmed();
                    threatCount = linelist.at(8).split("：").at(1).trimmed();
                } else if (linelist.at(1).split(":").size() == 2) {
                    // 扫描时间 eg:Scan Time:2020-09-09 16:49:13 https://pms.uniontech.com/zentao/bug-view-47031.html
                    dateTime = linelist.at(2).split(":").at(1) + ":" + linelist.at(2).split(":").at(2) + ":" + linelist.at(2).split(":").last();
                    scanType = linelist.at(13).split(">>").at(1).trimmed();
                    threatCount = linelist.at(8).split(":").at(1).trimmed();
                }
                scanlogInfo.datetime = dateTime;
                if (scanType == "0") {
                    scanlogInfo.scanType = tr("Full Scan");
                } else if (scanType == "1") {
                    scanlogInfo.scanType = tr("Quick Scan");
                } else {
                    scanlogInfo.scanType = tr("Custom Scan");
                }
                scanlogInfo.result = threatCount;
                // 文件名称
                scanlogInfo.filePath = m_logFile.at(i);
                ++m_curret;
                setCurrentProcess(m_curret);
                appendFileInfo(scanlogInfo);
                QApplication::processEvents();
            } else {
                // 不正确的文件保存下来  然后删除
                errorFiles.append(m_logFile.at(i));
            }
        }
    }
    // 设置按钮状态
    m_pBLog->setDisabled(false);
    // 全选状态判断
    m_checkBoxAll->setCheckState(Qt::CheckState::Unchecked);
    if (m_curret == 0) {
        // 没有隔离数据为不可以操作
        m_checkBoxAll->setDisabled(true);
    } else {
        // 有数据可以操作
        m_checkBoxAll->setDisabled(false);
    }

    // 删除异常文件
    for (int i = 0; i < errorFiles.size(); i++) {
        deletelogFile(errorFiles.at(i));
    }

    // 时间倒序排序 bug https://pms.uniontech.com/zentao/bug-view-55994.html
    sortByTableHeaderClicked(0);
}

// 打开指定文件
void NatiavScanLog::openLogFile(QString sFilepath)
{
    QDesktopServices::openUrl(QUrl::fromLocalFile(QFileInfo(sFilepath).absoluteFilePath()));
}

// 删除指定文件
void NatiavScanLog::deletelogFile(QString sFilepath)
{
    QFile file(sFilepath);
    // 判断文件是否存在
    if (file.exists()) {
        file.remove();
    }
}

// 更改table 因改变表头宽度
void NatiavScanLog::updateTableForWidth(int nLogicalIndex, int nOldSize, int nNewSize)
{
    Q_UNUSED(nOldSize);
    // 行数
    int count = m_model->rowCount();
    for (int i = 0; i < count; i++) {
        // 判断是第几列改变
        if (nLogicalIndex == TABLE_COL_TIME) {
            QWidget *widget = m_tableView->indexWidget(m_model->index(i, nLogicalIndex));
            QLabel *lable = widget->findChild<QLabel *>("datetime");
            // 得到每个字符的宽度
            QFontMetrics fontWidth(lable->font());
            //文件路径
            QString time = m_model->index(i, TABLE_COL_ADD_TIME).data(Qt::DisplayRole).toString();
            QString elideNote = fontWidth.elidedText(time, Qt::ElideMiddle, nNewSize - (2 * TABLE_SPACE) - 20);
            // 显示省略好的字符串
            lable->setText(elideNote);
            lable->setToolTip(time);
        } else if (nLogicalIndex == TABLE_COL_TYPE) {
            QWidget *widget = m_tableView->indexWidget(m_model->index(i, nLogicalIndex));
            QLabel *lable = widget->findChild<QLabel *>("scanType");
            // 得到每个字符的宽度
            QFontMetrics fontWidth(lable->font());
            // 得到每个字符的宽度
            QString scanType = m_model->index(i, TABLE_COL_STATUS).data(Qt::DisplayRole).toString();
            QString elideNote2 = fontWidth.elidedText(scanType, Qt::ElideMiddle, nNewSize - (2 * TABLE_SPACE));
            // 显示省略好的字符串
            lable->setText(elideNote2);
            lable->setToolTip(scanType);
        } else if (nLogicalIndex == TABLE_COL_RESULT) {
            QWidget *widget = m_tableView->indexWidget(m_model->index(i, nLogicalIndex));
            QLabel *lable = widget->findChild<QLabel *>("result");
            // 得到每个字符的宽度
            QFontMetrics fontWidth(lable->font());
            // 得到每个字符的宽度
            QString result = m_model->index(i, TABLE_COL_RES).data(Qt::DisplayRole).toString();
            if (result == "0") {
                // "未发现风险项";
                result = QString(tr("No threats found"));
            } else {
                // 发现%d个风险
                result = QString(tr("%1 threats found").arg(result));
            }
            QString elideNote3 = fontWidth.elidedText(result, Qt::ElideMiddle, nNewSize - (2 * TABLE_SPACE));
            // 显示省略好的字符串
            lable->setText(elideNote3);
            lable->setToolTip(result);
        } else {
            return;
        }
    }
}

// 刷新table 因字体改变
void NatiavScanLog::refreshTableByFontChange()
{
    // 行数
    int count = m_model->rowCount();
    // 获得没一列的宽度
    int wcol1 = m_tableView->columnWidth(TABLE_COL_TIME);
    int wcol2 = m_tableView->columnWidth(TABLE_COL_TYPE);
    int wcol3 = m_tableView->columnWidth(TABLE_COL_RESULT);
    for (int i = 0; i < count; i++) {
        // 第一列修改
        QWidget *widget = m_tableView->indexWidget(m_model->index(i, TABLE_COL_TIME));
        QLabel *lable = widget->findChild<QLabel *>("datetime");
        // 得到每个字符的宽度
        QFontMetrics fontWidth(lable->font());
        //文件路径
        QString time = m_model->index(i, TABLE_COL_ADD_TIME).data(Qt::DisplayRole).toString();
        QString elideNote = fontWidth.elidedText(time, Qt::ElideMiddle, wcol1 - (2 * TABLE_SPACE) - 20);
        // 显示省略好的字符串
        lable->setText(elideNote);
        lable->setToolTip(time);

        // 第二列修改
        QWidget *widget2 = m_tableView->indexWidget(m_model->index(i, TABLE_COL_TYPE));
        QLabel *lable2 = widget2->findChild<QLabel *>("scanType");
        // 得到每个字符的宽度
        QString scanType = m_model->index(i, TABLE_COL_STATUS).data(Qt::DisplayRole).toString();
        QString elideNote2 = fontWidth.elidedText(scanType, Qt::ElideMiddle, wcol2 - (2 * TABLE_SPACE));
        // 显示省略好的字符串
        lable2->setText(elideNote2);
        lable2->setToolTip(scanType);

        // 第三列修改
        QWidget *widget3 = m_tableView->indexWidget(m_model->index(i, TABLE_COL_RESULT));
        QLabel *lable3 = widget3->findChild<QLabel *>("result");
        // 得到每个字符的宽度
        QString result = m_model->index(i, TABLE_COL_RES).data(Qt::DisplayRole).toString();
        if (result == "0") {
            // "未发现风险项";
            result = QString(tr("No threats found"));
        } else {
            // 发现%d个风险
            result = QString(tr("%1 threats found").arg(result));
        }
        QString elideNote3 = fontWidth.elidedText(result, Qt::ElideMiddle, wcol3 - (2 * TABLE_SPACE));
        // 显示省略好的字符串
        lable3->setText(elideNote3);
        lable3->setToolTip(result);
    }
}

// 表头点击排序
void NatiavScanLog::sortByTableHeaderClicked(int index)
{
    // 根据不同的点击列  对应的列进行排序
    if (index == TABLE_COL_TIME) {
        // 第二列排序
        m_tableView->sortByColumn(TABLE_COL_ADD_TIME);
    } else if (index == TABLE_COL_TYPE) {
        // 第三列 排序
        m_tableView->sortByColumn(TABLE_COL_STATUS);
    } else if (index == TABLE_COL_RESULT) {
        // 第四列排序
        m_tableView->sortByColumn(TABLE_COL_RES);
    } else {
        return;
    }
}

void NatiavScanLog::refreshBtnLogText()
{
    QString sBtnLogText = tr("Delete Log");
    QFontMetrics fontmet(m_pBLog->font());
    QString elidedStr = fontmet.elidedText(sBtnLogText, Qt::TextElideMode::ElideMiddle, m_pBLog->width() - 10);
    m_pBLog->setText(elidedStr);
    if (fontmet.width(sBtnLogText) > (m_pBLog->width() - 10)) {
        m_pBLog->setToolTip(sBtnLogText);
    } else {
        m_pBLog->setToolTip("");
    }
}

// 当前行被选中
void NatiavScanLog::currentRowClicked(const QModelIndex& index)
{
    // 当前点击的位置坐标
    int row = index.row();
    int column = index.column();

    if (column != TABLE_COL_ACTION) {
        // 为了避免操作 不可以在操作列点击
        QWidget *widget = m_tableView->indexWidget(m_model->index(row, TABLE_COL_TIME));
        // 多选框对象
        QCheckBox *check = widget->findChild<QCheckBox *>("singleChecks");
        // 按钮的状态
        int status = check->checkState();
        // 改变按钮状态
        if (status == 0) {
            check->setCheckState(Qt::CheckState::Checked);
        } else {
            check->setCheckState(Qt::CheckState::Unchecked);
        }
        // 判断全选的状态
        checkBoxAllStatus();
    } else {
        return;
    }
}

// 判断全选按钮
void NatiavScanLog::checkBoxAllStatus()
{
    // 总行数
    int count = m_model->rowCount();
    // 选中状态的map
    QMap<int, int> rowMap;
    for (int i = 0; i < count; i++) {
        QWidget *widget = m_tableView->indexWidget(m_model->index(i, TABLE_COL_TIME));
        // 多选框对象
        QCheckBox *check = widget->findChild<QCheckBox *>("singleChecks");
        // 按钮的状态
        int status = check->checkState();
        switch (status) {
        case 0:
            rowMap.insert(i, 0);
            m_model->item(i, TABLE_COL_CHECK_STATUS)->setText("0");
            break;
        case 1:
            break;
        case 2:
            // 如果是选中状态移除
            rowMap.insert(i, 1);
            m_model->item(i, TABLE_COL_CHECK_STATUS)->setText("1");
            break;
        }
    }
    // 打沟的数量
    int tcount = 0;
    // 不打沟的数量
    int fcount = 0;
    QMapIterator<int, int> rowMapIterator(rowMap);
    rowMapIterator.toBack();
    while (rowMapIterator.hasPrevious()) {
        int value;
        rowMapIterator.previous();
        value = rowMapIterator.value();
        if (value == 0) {
            fcount++;
        } else if (value == 1) {
            tcount++;
        }
    }

    // 根据数量判断  全选状态
    if (tcount == count) {
        m_checkBoxAll->setCheckState(Qt::CheckState::Checked);
    } else if (fcount == count) {
        m_checkBoxAll->setCheckState(Qt::CheckState::Unchecked);
    } else {
        // 有一个没有选中  先把全选设为未选择状态   然后吧以前的选中都恢复
        m_checkBoxAll->setCheckState(Qt::CheckState::Unchecked);
        QMap<int, int>::iterator it;
        for (it = rowMap.begin(); it != rowMap.end(); ++it) {
            if (it.value() == 0) {
                int row = it.key();
                QWidget *widget = m_tableView->indexWidget(m_model->index(row, TABLE_COL_TIME));
                QCheckBox *check = widget->findChild<QCheckBox *>("singleChecks");
                check->setCheckState(Qt::CheckState::Unchecked);
            } else {
                int row = it.key();
                QWidget *widget = m_tableView->indexWidget(m_model->index(row, TABLE_COL_TIME));
                QCheckBox *check = widget->findChild<QCheckBox *>("singleChecks");
                check->setCheckState(Qt::CheckState::Checked);
            }
        }
    }
}

void NatiavScanLog::appendFileInfo(ScanLogInfo info)
{
    //锁
    DEFENDER_MUTEX_LOCKER(&SMutex::getInstance().m_mutex);
    //当前行
    int currentRow = m_model->rowCount();
    // 默认是没有选中
    m_model->setItem(currentRow, TABLE_COL_CHECK_STATUS, new QStandardItem(QString("%1").arg(0)));
    m_model->setItem(currentRow, TABLE_COL_FILE_NAME, new QStandardItem(QString("%1").arg(info.filePath)));
    m_model->setItem(currentRow, TABLE_COL_ADD_TIME, new QStandardItem(QString("%1").arg(info.datetime))); //时间
    m_model->setItem(currentRow, TABLE_COL_STATUS, new QStandardItem(QString("%1").arg(info.scanType))); //扫描出的类型
    m_model->setItem(currentRow, TABLE_COL_RES, new QStandardItem(QString("%1").arg(info.result))); //扫描出数据结果
    m_model->item(currentRow, TABLE_COL_RES)->setData(info.result.toInt(), Qt::ItemDataRole::EditRole);

    QWidget *widget1 = new QWidget(this);
    SET_ACC_NAME(widget1, appendfileWidget);
    QHBoxLayout *Layout1 = new QHBoxLayout;

    // 第一列
    Layout1->setContentsMargins(0, SPACING, TABLE_SPACE, SPACING);
    Layout1->setSpacing(TABLE_SPACE);
    QCheckBox *check = new QCheckBox(this);
    SET_ACC_NAME(check, line1_checkbox);
    check->setFixedSize(QSize(20, 20));
    // 多选框对象
    check->setObjectName("singleChecks");
    check->setCheckState(Qt::CheckState::Unchecked);
    Layout1->addWidget(check, 0, Qt::AlignLeft);
    // 复选框
    connect(check, SIGNAL(clicked()), this, SLOT(tableCheckItem()));

    QLabel *lable1 = new QLabel(this);
    SET_ACC_NAME(lable1, lable1);
    lable1->setObjectName("datetime");
    // 得到每个字符的宽度
    QFontMetrics fontWidth(lable1->font());
    // 最大宽度显示文字
    QString elideNote = fontWidth.elidedText(info.datetime, Qt::ElideMiddle, TABLE_COL_1_WIDTH - 10 - 25);
    // 显示省略好的字符串
    lable1->setText(elideNote);
    // 设置tooltips
    lable1->setToolTip(info.datetime);
    Layout1->addWidget(lable1, 0, Qt::AlignLeft);
    Layout1->addStretch(0);
    widget1->setLayout(Layout1);

    QWidget *widget2 = new QWidget(this);
    SET_ACC_NAME(widget2, widget2);
    QHBoxLayout *Layout2 = new QHBoxLayout;
    // 第三列
    Layout2->setContentsMargins(0, SPACING, TABLE_SPACE, SPACING);
    QLabel *lable2 = new QLabel(this);
    SET_ACC_NAME(lable2, lable2);
    lable2->setObjectName("scanType");
    // 最大宽度显示文字
    QString scanType = fontWidth.elidedText(info.scanType, Qt::ElideMiddle, TABLE_COL_2_WIDTH - 10);
    lable2->setText(scanType);
    lable2->setToolTip(scanType);
    Layout2->addWidget(lable2);
    widget2->setLayout(Layout2);

    QWidget *widget3 = new QWidget(this);
    SET_ACC_NAME(widget3, widget3);
    QHBoxLayout *Layout3 = new QHBoxLayout;
    // 第四列
    Layout3->setContentsMargins(0, SPACING, TABLE_SPACE, SPACING);
    QLabel *lable3 = new QLabel(this);
    SET_ACC_NAME(lable3, lable3);
    lable3->setObjectName("result");
    QString reslut;
    // 根据结果显示  相关文本
    if (info.result == "0") {
        // "未发现风险项";
        reslut = QString(tr("No threats found"));
    } else {
        // 发现%d个风险
        reslut = QString(tr("%1 threats found").arg(info.result));
    }
    // 最大宽度显示文字
    QString reslut1 = fontWidth.elidedText(reslut, Qt::ElideMiddle, TABLE_COL_3_WIDTH);
    lable3->setText(reslut1);
    lable3->setToolTip(reslut);
    Layout3->addWidget(lable3);
    widget3->setLayout(Layout3);

    QWidget *pwidget = new QWidget(this);
    SET_ACC_NAME(pwidget, widget);
    // 第五列
    QHBoxLayout *hlayout = new QHBoxLayout;
    hlayout->setContentsMargins(0, SPACING, TABLE_SPACE, SPACING);
    QPushButton *button = new QPushButton(this);
    SET_ACC_NAME(button, operationButton);
    button->setObjectName("pbOperation");
    // 操作显示栏
    button->setToolTip(tr("Action"));
    button->setIcon(getButtonIcon());

    // 操作图表大小设置
    button->setIconSize(QSize(ACTION_ICON_WIDTH, ACTION_ICON_HEIGHT));
    button->setFixedSize(ACTION_ICON_WIDTH, ACTION_ICON_HEIGHT);
    button->setFlat(true);
    button->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    hlayout->addWidget(button);
    pwidget->setLayout(hlayout);
    // 文件路径
    QString pathfile = m_currentDir + info.filePath;
//    connect(button, &PushButton::clicked, this, [=] {
//        // 打开文件路径
//        this->openLogFile(pathfile);
//    });

    // 设置每列的控件
    m_tableView->setIndexWidget(m_model->index(currentRow, TABLE_COL_TIME), widget1);
    m_tableView->setIndexWidget(m_model->index(currentRow, TABLE_COL_TYPE), widget2);
    m_tableView->setIndexWidget(m_model->index(currentRow, TABLE_COL_RESULT), widget3);
    m_tableView->setIndexWidget(m_model->index(currentRow, TABLE_COL_ACTION), pwidget);
    // 缓冲作用
    m_model->setItem(currentRow + 1, 0, new QStandardItem);
    m_model->removeRow(currentRow + 1);
    // 设置每列的宽度
    m_tableView->setColumnWidth(TABLE_COL_TIME, TABLE_COL_1_WIDTH);
    m_tableView->setColumnWidth(TABLE_COL_TYPE, TABLE_COL_2_WIDTH);
    m_tableView->setColumnWidth(TABLE_COL_RESULT, TABLE_COL_3_WIDTH);
    m_tableView->setColumnWidth(TABLE_COL_ACTION, TABLE_COL_4_WIDTH);
    // 隐藏列
    m_tableView->setColumnHidden(TABLE_COL_CHECK_STATUS, true);
    m_tableView->setColumnHidden(TABLE_COL_FILE_NAME, true);
    m_tableView->setColumnHidden(TABLE_COL_ADD_TIME, true);
    m_tableView->setColumnHidden(TABLE_COL_STATUS, true);
    m_tableView->setColumnHidden(TABLE_COL_RES, true);
}

void NatiavScanLog::setCurrentProcess(int nCurrent)
{
    m_proLable->setText(QString("%1").arg(nCurrent));
}

// 校验日志文件是否正确 输入参数是每行拼接的字符
bool NatiavScanLog::checkContext(QStringList list)
{
    // 第二行 校验病毒版本 由于翻译中文的时候  是中文冒号 英文是英文冒号 比如：病毒库版本：20.9.1.19
    if ((list.at(1).split("：").size() == 2) || (list.at(1).split(":").size() == 2)) {
        // 第三行 校验扫描时间 例如 扫描时间：2020-09-05 18:41:55
        if ((list.at(2).split("：").size() == 2) || (list.at(2).split(":").size() == 4)) {
            // 第八行 校验病毒个数 例如 扫描文件数：525
            if ((list.at(7).split("：").size() == 2) || (list.at(7).split(":").size() == 2)) {
                // 第14行 扫描类型
                if (list.at(13).split(">>").size() == 2) {
                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        } else {
            return false;
        }
    } else {
        return false;
    }
}

// 获得按钮图标图片类型
QIcon NatiavScanLog::getButtonIcon()
{
    // 判断当前主题类型
//    if (m_guiHelper->themeType() == DGuiApplicationHelper::ColorType::LightType) {
        // 如果是浅色主题
        return QIcon::fromTheme(ANTIAV_LOG_DETAIL_LIGHT);
//    } else {
//        return QIcon::fromTheme(ANTIAV_LOG_DETAIL_DARK);
//    }
}

// 事件过滤
bool NatiavScanLog::eventFilter(QObject *obj, QEvent *event)
{
    if (this == obj) {
        // 如果当前是字体改变的事件
        if (event->type() == QEvent::FontChange) {
            // 刷新列表
            refreshTableByFontChange();

            // 刷新病毒查杀日志 按钮
            refreshBtnLogText();
        }
    }
    return QWidget::eventFilter(obj, event);
}

// 全选
void NatiavScanLog::checkAll(int nStatus)
{
    // 行数
    int count = m_model->rowCount();
    for (int i = 0; i < count; i++) {
        QWidget *widget = m_tableView->indexWidget(m_model->index(i, TABLE_COL_TIME));
        QCheckBox *check = widget->findChild<QCheckBox *>("singleChecks");
        switch (nStatus) {
        case 0:
            check->setCheckState(Qt::CheckState::Unchecked);
            break;
        case 1:
            break;
        case 2:
            check->setCheckState(Qt::CheckState::Checked);
            break;
        }
    }
}

// 删除日志
void NatiavScanLog::deleteLog()
{
    // 总行数
    int count = m_model->rowCount();
    // 选中状态的map
    QMap<int, int> rowMap;
    for (int i = 0; i < count; i++) {
        QWidget *widget = m_tableView->indexWidget(m_model->index(i, TABLE_COL_TIME));
        // 多选框对象
        QCheckBox *check = widget->findChild<QCheckBox *>("singleChecks");
        // 按钮的状态
        int status = check->checkState();
        switch (status) {
        case 0:
            rowMap.insert(i, 0);
            break;
        case 1:
            break;
        case 2:
            // 1代表是选中状态
            rowMap.insert(i, 1);
            break;
        }
    }

    int key;
    int value;
    int nDeleteCount = 0;

    // map  迭代
    QMapIterator<int, int> rowMapIterator(rowMap);
    rowMapIterator.toBack();

    // 是否在最后一个
    while (rowMapIterator.hasPrevious()) {
        rowMapIterator.previous();
        key = rowMapIterator.key();
        value = rowMapIterator.value();
        if (value == 1) {
            // 文件名
            QString fileName = m_model->index(key, TABLE_COL_FILE_NAME).data(Qt::DisplayRole).toString();
            // 文件路径
            QString filepath = m_currentDir + fileName;
            deletelogFile(filepath);
            m_model->removeRow(key);
            nDeleteCount++;
        }
    }

    // 添加安全日志
    DBUS_NOBLOCK_INVOKE(m_monitorInterFaceServer, "AddSecurityLog", SECURITY_LOG_TYPE_ANTIAV, tr("Scan logs deleted: %1").arg(nDeleteCount));

    // 删除完后剩余的总行数
    int count1 = m_model->rowCount();
    setCurrentProcess(count1);
    if (count1 == 0) {
        // 表格中没有数据了 去选不会选中不至于灰色
        m_checkBoxAll->setCheckState(Qt::CheckState::Unchecked);
        m_checkBoxAll->setDisabled(true);
    }
}

// table 单选对象
void NatiavScanLog::tableCheckItem()
{
    checkBoxAllStatus();
}

// 主题切换
void NatiavScanLog::themeTypeChange(ColorType themeType)
{
    Q_UNUSED(themeType);
    //总行数
    int count = m_model->rowCount();
    for (int i = 0; i < count; i++) {
        QWidget *widget = m_tableView->indexWidget(m_model->index(i, TABLE_COL_ACTION));
        QPushButton *button = widget->findChild<QPushButton *>("pbOperation");
        button->setIcon(getButtonIcon());
    }
}
